import * as THREE from 'three';
import dat from 'dat.gui';
import {
  initStats,
  initRenderer,
  initCamera,
  addHouseAndTree,
  initTrackballControls
} from '../util';

export function init03(width, height) {
  // 使用默认设置
  const stats = initStats();
  const renderer = initRenderer(width, height);

  const camera = initCamera(width, height);
  const trackballControls = initTrackballControls(camera, renderer);
  const clock = new THREE.Clock();

  // 创建一个场景，它将包含我们所有的元素，如对象，相机和灯光。
  const scene = new THREE.Scene();

  // 添加一个简单的场景
  addHouseAndTree(scene);

  // 添加环境光源
  const ambientLight = new THREE.AmbientLight('#0c0c0c');
  scene.add(ambientLight);

  // 点光源
  const pointColor = '#ccffcc';
  const pointLight = new THREE.PointLight(pointColor);
  pointLight.decay = 0.1;
  pointLight.castShadow = true;
  scene.add(pointLight);

  const lightHelper = new THREE.PointLightHelper(pointLight);
  // scene.add(lightHelper);

  const cameraHelper = new THREE.CameraHelper(pointLight.shadow.camera);
  // scene.add(cameraHelper)

  // 添加一个模拟点光源的小球体
  const sphereLight = new THREE.SphereGeometry(0.2);
  const sphereLightMaterial = new THREE.MeshBasicMaterial({
    color: 0xac6c25
  });
  const sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);
  sphereLightMesh.position.set(3, 0, 5);
  scene.add(sphereLightMesh);

  // 调用渲染函数
  // 用于确定灯光动画的切换点
  let invert = 1;
  let phase = 0;

  const controls = setupControls();

  render();

  function render() {
    lightHelper.update();
    cameraHelper.update();

    stats.update();
    pointLight.position.copy(sphereLightMesh.position);
    trackballControls.update(clock.getDelta());

    // 移动模拟光源
    if (phase > 2 * Math.PI) {
      invert = invert * -1;
      phase -= 2 * Math.PI;
    } else {
      phase += controls.rotationSpeed;
    }
    sphereLightMesh.position.z = +(25 * Math.sin(phase));
    sphereLightMesh.position.x = +(14 * Math.cos(phase));
    sphereLightMesh.position.y = 5;

    if (invert < 0) {
      const pivot = 14;
      sphereLightMesh.position.x =
        invert * (sphereLightMesh.position.x - pivot) + pivot;
    }

    renderer.render(scene, camera);
    requestAnimationFrame(render);
  }

  function setupControls() {
    const controls = new (function() {
      this.rotationSpeed = 0.01;
      this.bouncingSpeed = 0.03;
      this.ambientColor = ambientLight.color.getStyle();
      this.pointColor = pointLight.color.getStyle();
      this.intensity = 1;
      this.distance = pointLight.distance;
    })();

    const gui = new dat.GUI();
    gui.addColor(controls, 'ambientColor').onChange(function(e) {
      ambientLight.color = new THREE.Color(e);
    });

    gui.addColor(controls, 'pointColor').onChange(function(e) {
      pointLight.color = new THREE.Color(e);
    });

    gui.add(controls, 'distance', 0, 100).onChange(function(e) {
      pointLight.distance = e;
    });

    gui.add(controls, 'intensity', 0, 3).onChange(function(e) {
      pointLight.intensity = e;
    });

    return controls;
  }
}
